```vue
<template>
  <div class="manage-poi">
    <el-card class="manage-card animated">
      <h1 class="title">房价数据管理</h1>
      <el-form :inline="true" :model="searchForm" class="search-bar" @submit.prevent>
        <el-form-item label="名称">
          <el-input v-model="searchForm.name" placeholder="请输入名称" clearable />
        </el-form-item>
        <el-form-item label="行政区">
          <el-input v-model="searchForm.district" placeholder="请输入行政区" clearable />
        </el-form-item>
        <el-form-item label="商圈">
          <el-input v-model="searchForm.sub_district" placeholder="请输入商圈" clearable />
        </el-form-item>
        <el-form-item label="最低单价">
          <el-input-number
            v-model="searchForm.price_min"
            placeholder="最低单价 (万元/㎡)"
            :min="0"
            :precision="2"
            style="width: 150px;"
          />
        </el-form-item>
        <el-form-item label="最高单价">
          <el-input-number
            v-model="searchForm.price_max"
            placeholder="最高单价 (万元/㎡)"
            :min="0"
            :precision="2"
            style="width: 150px;"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" class="action-button">搜索</el-button>
          <el-button @click="resetSearch" class="action-button">重置</el-button>
        </el-form-item>
      </el-form>

      <el-table
        :data="propertyStore.propertyList"
        style="width: 100%"
        stripe
        @sort-change="handleSortChange"
        class="manage-table"
      >
        <el-table-column prop="id" label="ID" width="50" />
        <el-table-column prop="name" label="名称" />
        <el-table-column prop="district" label="行政区" />
        <el-table-column prop="sub_district" label="商圈" />
        <el-table-column label="上架时间">
          <template #default="{ row }">
            {{ row.listing_year }}, {{ formatMonth(row.listing_month) }}
          </template>
        </el-table-column>
        <el-table-column label="经纬度">
          <template #default="{ row }">
            {{ row.coordinates?.[1] }}, {{ row.coordinates?.[0] }}
          </template>
        </el-table-column>
        <el-table-column prop="avg_unit_price" label="平均单价" sortable />
        <el-table-column prop="median_unit_price" label="中位单价" sortable />
        <el-table-column prop="min_unit_price" label="最低单价" sortable />
        <el-table-column prop="max_unit_price" label="最高单价" sortable />
        <el-table-column prop="avg_total_price" label="平均总价" sortable />
        <el-table-column prop="median_total_price" label="中位总价" sortable />
        <el-table-column prop="min_total_price" label="最低总价" sortable />
        <el-table-column prop="max_total_price" label="最高总价" sortable />
        <el-table-column label="操作" width="160" fixed="right">
          <template #default="{ row }">
            <el-button size="small" @click="editProperty(row)" class="action-button">编辑</el-button>
            <br>
            <el-button size="small" type="danger" @click="deleteProperty(row.id)" class="action-button" >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="bottom-right-button">
        <el-button
          type="success"
          @click="openDialog"
          class="action-button"
          :disabled="dialogVisible"
        >新增</el-button>
        <el-button type="danger" @click="handleExit" class="action-button">退出</el-button>
      </div>

      <el-pagination
        background
        layout="prev, pager, next"
        :total="propertyStore.totalItems"
        :page-size="propertyStore.pageSize"
        :current-page="propertyStore.currentPage"
        @current-change="handlePageChange"
        class="pagination"
      />

      <el-dialog
        :title="dialogTitle"
        v-model="dialogVisible"
        class="dialog"
        :width="dialogWidth"
        :append-to-body="true"
      >
        <el-form
          :model="form"
          :rules="rules"
          label-width="100px"
          label-position="top"
          ref="formRef"
          class="dialog-form"
        >
          <el-form-item label="名称" prop="name">
            <el-input v-model="form.name" />
          </el-form-item>
          <el-form-item label="行政区" prop="district">
            <el-input v-model="form.district" />
          </el-form-item>
          <el-form-item label="商圈" prop="sub_district">
            <el-input v-model="form.sub_district" />
          </el-form-item>
          <el-form-item label="上架年份" prop="listing_year">
            <el-input-number v-model="form.listing_year" :controls="false" style="width: 100%;" />
          </el-form-item>
          <el-form-item label="上架月份" prop="listing_month">
            <el-input-number v-model="form.listing_month" :min="1" :max="12" style="width: 100%;" />
          </el-form-item>
          <el-form-item label="经度" prop="longitude">
            <el-input v-model.number="form.longitude" />
          </el-form-item>
          <el-form-item label="纬度" prop="latitude">
            <el-input v-model.number="form.latitude" />
          </el-form-item>
          <el-form-item label="平均单价" prop="avg_unit_price">
            <el-input v-model.number="form.avg_unit_price" />
          </el-form-item>
          <el-form-item label="中位单价" prop="median_unit_price">
            <el-input v-model.number="form.median_unit_price" />
          </el-form-item>
          <el-form-item label="最低单价" prop="min_unit_price">
            <el-input v-model.number="form.min_unit_price" />
          </el-form-item>
          <el-form-item label="最高单价" prop="max_unit_price">
            <el-input v-model.number="form.max_unit_price" />
          </el-form-item>
          <el-form-item label="平均总价" prop="avg_total_price">
            <el-input v-model.number="form.avg_total_price" />
          </el-form-item>
          <el-form-item label="中位总价" prop="median_total_price">
            <el-input v-model.number="form.median_total_price" />
          </el-form-item>
          <el-form-item label="最低总价" prop="min_total_price">
            <el-input v-model.number="form.min_total_price" />
          </el-form-item>
          <el-form-item label="最高总价" prop="max_total_price">
            <el-input v-model.number="form.max_total_price" />
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveProperty">保存</el-button>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
import { usePropertyStore } from '@/stores/properties';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';

const propertyStore = usePropertyStore();
const router = useRouter();
const dialogVisible = ref(false);
const formRef = ref(null);
const form = ref({});
const isEdit = ref(false);
const sortParams = ref({ prop: null, order: null });

const dialogTitle = computed(() => (isEdit.value ? '编辑房产条目' : '新增房产条目'));
const dialogWidth = computed(() => (window.innerWidth < 768 ? '90%' : '600px'));

const searchForm = ref({
  name: '',
  district: '',
  sub_district: '',
  price_min: null,
  price_max: null,
});

const rules = {
  name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  district: [{ required: true, message: '请输入行政区', trigger: 'blur' }],
  sub_district: [{ required: true, message: '请输入商圈', trigger: 'blur' }],
  listing_year: [
    { required: true, message: '请输入上架年份', trigger: 'blur' },
    { type: 'number', message: '年份必须是数字', trigger: 'blur' },
  ],
  listing_month: [
    { required: true, message: '请输入上架月份', trigger: 'blur' },
    { type: 'number', min: 1, max: 12, message: '月份必须在 1-12 之间', trigger: 'blur' },
  ],
  longitude: [
    { required: true, message: '请输入经度', trigger: 'blur' },
    { type: 'number', message: '经度必须是数字', trigger: 'blur' },
  ],
  latitude: [
    { required: true, message: '请输入纬度', trigger: 'blur' },
    { type: 'number', message: '纬度必须是数字', trigger: 'blur' },
  ],
  avg_unit_price: [
    { required: true, message: '请输入平均单价', trigger: 'blur' },
    { type: 'number', message: '平均单价必须是数字', trigger: 'blur' },
  ],
  median_unit_price: [
    { required: true, message: '请输入中位单价', trigger: 'blur' },
    { type: 'number', message: '中位单价必须是数字', trigger: 'blur' },
  ],
  min_unit_price: [
    { required: true, message: '请输入最低单价', trigger: 'blur' },
    { type: 'number', message: '最低单价必须是数字', trigger: 'blur' },
  ],
  max_unit_price: [
    { required: true, message: '请输入最高单价', trigger: 'blur' },
    { type: 'number', message: '最高单价必须是数字', trigger: 'blur' },
  ],
  avg_total_price: [
    { required: true, message: '请输入平均总价', trigger: 'blur' },
    { type: 'number', message: '平均总价必须是数字', trigger: 'blur' },
  ],
  median_total_price: [
    { required: true, message: '请输入中位总价', trigger: 'blur' },
    { type: 'number', message: '中位总价必须是数字', trigger: 'blur' },
  ],
  min_total_price: [
    { required: true, message: '请输入最低总价', trigger: 'blur' },
    { type: 'number', message: '最低总价必须是数字', trigger: 'blur' },
  ],
  max_total_price: [
    { required: true, message: '请输入最高总价', trigger: 'blur' },
    { type: 'number', message: '最高总价必须是数字', trigger: 'blur' },
  ],
};

onMounted(() => {
  // 在组件挂载后立即获取第一页数据
  propertyStore.fetchProperties({ page: 1 });
});

function formatMonth(listingMonth) {
  if (!listingMonth && listingMonth !== 0) return '';
  const month = parseFloat(listingMonth);
  return Math.floor(month % 1 * 100) || Math.floor(month);
}

function openDialog() {
  try {
    console.log('Opening dialog...');
    isEdit.value = false;
    form.value = {
      name: '',
      district: '',
      sub_district: '',
      listing_year: null,
      listing_month: null,
      longitude: null,
      latitude: null,
      avg_unit_price: null,
      median_unit_price: null,
      min_unit_price: null,
      max_unit_price: null,
      avg_total_price: null,
      median_total_price: null,
      min_total_price: null,
      max_total_price: null,
    };
    dialogVisible.value = true;
    console.log('Dialog should be visible, dialogVisible:', dialogVisible.value);
  } catch (error) {
    console.error('Failed to open dialog:', error);
    ElMessage.error('无法打开新增对话框，请稍后重试');
  }
}

function editProperty(row) {
  try {
    console.log('Editing property:', row);
    isEdit.value = true;
    form.value = { ...row, longitude: row.coordinates[0], latitude: row.coordinates[1] };
    dialogVisible.value = true;
    console.log('Dialog should be visible, dialogVisible:', dialogVisible.value);
  } catch (error) {
    console.error('Failed to open edit dialog:', error);
    ElMessage.error('无法打开编辑对话框，请稍后重试');
  }
}

function handleSearch() {
  const queryParams = {
    page: 1,
    name: searchForm.value.name,
    district: searchForm.value.district,
    sub_district: searchForm.value.sub_district,
    price_min: searchForm.value.price_min,
    price_max: searchForm.value.price_max,
    sort_by: sortParams.value.prop,
    sort_order: sortParams.value.order,
  };
  ['name', 'district', 'sub_district', 'price_min', 'price_max', 'sort_by', 'sort_order'].forEach(key => {
    if (!queryParams[key] && queryParams[key] !== 0) {
      delete queryParams[key];
    }
  });
  propertyStore.fetchProperties(queryParams);
}

function resetSearch() {
  searchForm.value = { name: '', district: '', sub_district: '', price_min: null, price_max: null };
  sortParams.value = { prop: null, order: null };
  propertyStore.fetchProperties({ page: 1 });
}

const handleExit = async () => {
  await router.push('/admin');
};

async function saveProperty() {
  try {
    await formRef.value.validate();
    const payload = {
      id: isEdit.value ? form.value.id : null,
      community: form.value.name,
      region: form.value.district,
      business_district: form.value.sub_district,
      listing_year: form.value.listing_year,
      listing_month: form.value.listing_month,
      longitude: form.value.longitude,
      latitude: form.value.latitude,
      unit_price_avg: form.value.avg_unit_price,
      unit_price_median: form.value.median_unit_price,
      unit_price_min: form.value.min_unit_price,
      unit_price_max: form.value.max_unit_price,
      total_price_avg: form.value.avg_total_price,
      total_price_median: form.value.median_total_price,
      total_price_min: form.value.min_total_price,
      total_price_max: form.value.max_total_price,
    };
    await (isEdit.value ? propertyStore.updateProperty(payload) : propertyStore.createProperty(payload));
    ElMessage.success('保存成功');
    await propertyStore.fetchProperties({
      page: propertyStore.currentPage,
      name: searchForm.value.name,
      district: searchForm.value.district,
      sub_district: searchForm.value.sub_district,
      price_min: searchForm.value.price_min,
      price_max: searchForm.value.price_max,
      sort_by: sortParams.value.prop,
      sort_order: sortParams.value.order,
    });
    dialogVisible.value = false;
  } catch (error) {
    console.error('Save failed:', error);
    ElMessage.error('保存失败，请检查输入');
  }
}

async function deleteProperty(id) {
  try {
    await propertyStore.deleteProperty(id);
    ElMessage.success('删除成功');
    await propertyStore.fetchProperties({
      page: propertyStore.currentPage,
      name: searchForm.value.name,
      district: searchForm.value.district,
      sub_district: searchForm.value.sub_district,
      price_min: searchForm.value.price_min,
      price_max: searchForm.value.price_max,
      sort_by: sortParams.value.prop,
      sort_order: sortParams.value.order,
    });
  } catch (error) {
    console.error('Delete failed:', error);
    ElMessage.error('删除失败');
  }
}

function handlePageChange(newPage) {
  const queryParams = {
    page: newPage,
    name: searchForm.value.name,
    district: searchForm.value.district,
    sub_district: searchForm.value.sub_district,
    price_min: searchForm.value.price_min,
    price_max: searchForm.value.price_max,
    sort_by: sortParams.value.prop,
    sort_order: sortParams.value.order,
  };
  ['name', 'district', 'sub_district', 'price_min', 'price_max', 'sort_by', 'sort_order'].forEach(key => {
    if (!queryParams[key] && queryParams[key] !== 0) {
      delete queryParams[key];
    }
  });
  propertyStore.fetchProperties(queryParams);
}

function handleSortChange({ prop, order }) {
  sortParams.value = { prop, order: order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : null };
  const queryParams = {
    page: propertyStore.currentPage,
    name: searchForm.value.name,
    district: searchForm.value.district,
    sub_district: searchForm.value.sub_district,
    price_min: searchForm.value.price_min,
    price_max: searchForm.value.price_max,
    sort_by: sortParams.value.prop,
    sort_order: sortParams.value.order,
  };
  ['name', 'district', 'sub_district', 'price_min', 'price_max', 'sort_by', 'sort_order'].forEach(key => {
    if (!queryParams[key] && queryParams[key] !== 0) {
      delete queryParams[key];
    }
  });
  propertyStore.fetchProperties(queryParams);
}
</script>

<style scoped>
@keyframes slideUpFadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.manage-poi {
  padding: 20px;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}

.manage-card {
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  padding: 20px;
  background: #ffffff;
  animation: slideUpFadeIn 0.7s ease-out forwards;
}

.title {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 20px;
  text-align: center;
}

.search-bar {
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.action-button {
  border-radius: 8px;
  padding: 10px 20px;
  transition: all 0.3s ease;
}

.action-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.manage-table {
  border-radius: 8px;
  overflow: hidden;
}

.pagination {
  margin-top: 20px;
  text-align: center;
}

.bottom-right-button {
  margin-top: 20px;
  text-align: right;
}

.dialog-form {
  max-height: 60vh;
  overflow-y: auto;
  padding-right: 10px;
}

:deep(.el-dialog) {
  z-index: 2000 !important; /* 确保对话框在最上层 */
}

:deep(.el-input__wrapper),
:deep(.el-input-number__wrapper) {
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  background-color: rgba(255, 255, 255, 0.8);
}

:deep(.el-input__wrapper.is-focus),
:deep(.el-input-number__wrapper.is-focus) {
  background-color: #fff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.3);
}

@media (max-width: 768px) {
  .manage-poi {
    padding: 10px;
  }

  .manage-card {
    padding: 15px;
  }

  .title {
    font-size: 20px;
  }

  .search-bar {
    flex-direction: column;
    align-items: stretch;
  }

  .action-button {
    padding: 8px 12px;
    font-size: 14px;
  }

  .dialog-form {
    max-height: 70vh;
  }

  :deep(.el-dialog) {
    margin-top: 10vh !important;
    z-index: 2000 !important;
  }
}
</style>
